from django.contrib import auth as django_auth
from django.db.models import Q

from rest_framework import exceptions
from rest_framework import generics
from rest_framework import permissions
from rest_framework import response
from rest_framework import views
from rest_framework.authtoken.models import Token
from rest_framework import status
from account import models as models_account
from utils import utils
from account import tasks
from django.contrib.auth.models import User
import rest_framework as drf
import datetime

from . import serializers


def validate_phone(value):
    if not utils.is_phone(value):
        raise serializers.ValidationError('手机号码格式错误')


class AccountProfileView(generics.RetrieveUpdateAPIView):
    serializer_class = serializers.AccountProfileSerializer
    permission_classes = (permissions.IsAuthenticated,)

    def get_object(self):
        return self.request.user.account


class AccountCreateView(generics.CreateAPIView):
    serializer_class = serializers.AccountSerializer

    def validate_phone(self, value):
        if not utils.is_phone(value):
            raise drf.serializers.ValidationError('手机号格式错误')
        if models_account.Account.objects.filter(phone=value).exists():
            raise drf.serializers.ValidationError('该手机号已经注册')
        return value

    def validate_sms_code(self, phone, code):
        record_obj = models_account.SmsRecord.objects.filter(phone=phone).first()
        if not record_obj:
            raise drf.serializers.ValidationError('请先发送验证码！')
        if record_obj.code!=code:
            raise drf.serializers.ValidationError('验证码输入错误！')

        return record_obj
    def validate_email(self, value):
        if not utils.is_email(value):
            raise drf.serializers.ValidationError('邮箱格式错误')
        if models_account.Account.objects.filter(email=value).exists():
            raise drf.serializers.ValidationError('该邮箱已经注册！')
        return value

    def post(self, request, *args, **kwargs):
        sms_code=request.data.get('sms_code')
        password=request.data.get('password')
        college=request.data.get('college')
        real_name=request.data.get('real_name')
        nickname=request.data.get('nickname')
        role=request.data.get('role')
        email=request.data.get('email')

        phone=AccountCreateView.validate_phone(self, request.data.get('phone'))
        AccountCreateView.validate_sms_code(self, phone, sms_code)
        AccountCreateView.validate_email(self, email)
        role_eu = ['1', '2']
        if not role in role_eu:
            raise drf.serializers.ValidationError('role参数错误')


        user = User.objects.create_user(
                username=phone,
                password=password
            )

        # Token
        token = Token.objects.create(user=user)

        # Account
        account = models_account.Account.objects.create(
                user=user,
                phone=phone,
                college=college,
                role=role,
                real_name=real_name,
                nickname=nickname,
                email=email,
        )

        # member Info
        if role=="1":
            student_number=request.data.get('student_number')
            major=request.data.get('major')
            stu=models_account.StudentInfo.objects.create(
                student_number=student_number,
                major=major,
            )
            account.member_id=stu.id

        elif role=="2":
            job_number = request.data.get('job_number')
            position = request.data.get('position')
            teacher=models_account.TeacherInfo.objects.create(
                job_number=job_number,
                position=position,
            )
            account.member_id = teacher.id

        account.save()

        data=serializers.AccountSerializer(account).data
        data['token'] = token.key

        return response.Response(data)

class AccountLoginView(views.APIView):
    serializer_class = serializers.AccountLoginSerializer

    def post(self, request):
        username = request.data.get('username')
        password = request.data.get('password')

        try:
            account = models_account.Account.objects.get(
                Q(phone=username) | Q(email=username)
            )
        except:
            raise exceptions.PermissionDenied('用户不存在')


        user = django_auth.authenticate(
                username=account.user.username, password=password
            )
        if not user:
            raise exceptions.PermissionDenied('用户名或密码错误')
        else:
            django_auth.login(request, user)

        account_data = serializers.AccountProfileSerializer(account).data
        token_obj, created = Token.objects.get_or_create(user=user)
        account_data.update(token=token_obj.key)
        return response.Response(account_data)


class AccountLogoutView(views.APIView):
    permission_classes = (permissions.IsAuthenticated,)

    def post(self, request):
        django_auth.logout(request)
        return response.Response('感谢您今天在本站花费了一些宝贵时间')


class SmsCreateView(generics.CreateAPIView):
    serializer_class = serializers.SmsRecordSerializer


class AccountInfoView(views.APIView):
    permission_classes = (permissions.IsAuthenticated,)
    serializer_class=serializers.AccountInfoSerializer

    def get(self, request):
        account=request.user.account

        info=serializers.AccountInfoSerializer(account).data
        return response.Response(info)


class AccountChangePwdView(generics.CreateAPIView):
    permission_classes = (permissions.IsAuthenticated,)
    serializer_class=serializers.AccountChangePwdSerializer

    def post(self, request):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        serializer.set_password(data=request.data)
        return response.Response(status=status.HTTP_200_OK)

class AccountAvatarView(generics.RetrieveUpdateAPIView):
    permission_classes = (permissions.IsAuthenticated,)
    serializer_class=serializers.AccountAvatarSerializer

    def get_object(self):
        try:
            account=self.request.user.account
        except :
            account=None
        return account

class AccountResetPwdView(generics.CreateAPIView):
    serializer_class=serializers.AccountResetPwdSerializer

    def post(self, request):
        phone = request.data.get('phone')
        sms_code=request.data.get('sms_code')
        password=request.data.get('password')

        try:
            user=User.objects.get(username=phone)
        except:
            drf.serializers.ValidationError("该手机号未注册！")

        record_obj = models_account.SmsRecord.objects.filter(phone=phone).first()

        if not record_obj :
            raise drf.serializers.ValidationError('请先发送验证码！')
        else:

            delta_time= datetime.datetime.utcnow()-record_obj.create_time.replace(tzinfo=None)
            if delta_time.days*3600+delta_time.seconds>600:
                raise drf.serializers.ValidationError('请先发送验证码！')

        if record_obj.code!=sms_code:
            raise drf.serializers.ValidationError('验证码输入错误！')
        else:
            user.set_password(password)
            user.save()


        return response.Response("修改密码成功！")


class AccountUpdateClassView(views.APIView):
    permission_classes = (permissions.IsAuthenticated,)

    def post(self,request):
        account = request.user.account
        member_id = account.member_id
        class_id=request.data.get('class_id')

        if not class_id.isdigit():
            pass
            #raise drf.serializers.ValidationError('class_id必须是数字')
        else:
            try:
                models_account.Class.objects.get(id=class_id)
            except:
                raise drf.serializers.ValidationError('未找到班级')

        if account.role == "2":
            raise drf.serializers.ValidationError('无效操作')
        elif account.role=='1':
            try:
                info=models_account.StudentInfo.objects.get(id=member_id)
                info.class_id=class_id
                info.save()
            except:
                raise drf.serializers.ValidationError('未找到对应信息')

        return response.Response("保存成功！")

